package util

import (
	"bytes"
	"fmt"
	"go.uber.org/zap"
	"io"
	"os"
	"os/exec"
	"runtime"
	"strings"
	"wf-deploy-agent/consts"
)

func buildCmdText(commandName string, params ...string) string {
	cmdText := commandName + consts.BlankSeparator + strings.Join(params, consts.BlankSeparator)
	return cmdText
}

func buildCmdObject(commandName string, params ...string) *exec.Cmd {
	osType := strings.ToLower(runtime.GOOS)
	cmdText := buildCmdText(commandName, params...)
	if osType == "windows" {
		return exec.Command("cmd", "/c", "start "+cmdText)
	}

	finalCmdText := fmt.Sprintf("%s;%s", "source /etc/profile", cmdText)
	return exec.Command("/bin/bash", "-c", finalCmdText)
}

func Exec(cmd string, args ...string) ([]byte, error) {
	if err := recover(); err != nil {
		zap.L().Sugar().Errorln(err)
	}

	full := cmd + " " + strings.Join(args, " ")
	zap.L().Sugar().Debugf("开始执行命令【%s】", full)
	var stdoutBuf bytes.Buffer
	command := buildCmdObject(cmd, args...)
	stdoutIn, _ := command.StdoutPipe()
	var errStdout error
	stdout := io.MultiWriter(os.Stdout, &stdoutBuf)
	err := command.Start()
	if err != nil {
		zap.L().Sugar().Errorf("cmd.Start() failed with '%s'\n", err)
	}

	go func() {
		_, errStdout = io.Copy(stdout, stdoutIn)
	}()

	err = command.Wait()
	if err != nil {
		return nil, err
	}

	if errStdout != nil {
		return nil, errStdout
	}

	zap.L().Sugar().Debugf("结束执行命令【%s】", full)

	return stdoutBuf.Bytes(), nil
}

func Start(cmd string, args ...string) error {
	command := buildCmdObject(cmd, args...)
	full := cmd + " " + strings.Join(args, " ")
	zap.L().Sugar().Debugf("开始执行命令【%s】", full)
	return command.Start()
}
